#include <iostream>

#include "PlayState.h"
#include "TextureManager.h"
#include "Game.h"
#include "Player.h"
#include "Utils.h"
#include "InputHangdler.h"
#include "PauseState.h"
#include "OverState.h"

#define FLAG 1
#define BOUDING_BOX		1
#define BOUDING_SQUARE	2
#define PIXEL_BASED		3


const string PlayState::s_playID = "PLAY";

bool PlayState::m_bPause = true;

Point collision;
Point collisionTwo;

bool GetInside(float x, float y)
{
	if (x < 0 || x > 800 || y < 0 || y > 480)
		return true;
	else
		return false;
}

PlayState::PlayState()
{
	m_bPause = false;
	//m_bHoldStop = false;
	m_pWindow = NULL;
	timeGenarateCreep = 0.0f;
	// do nothing
}

void PlayState::render()
{
	
	
	
	m_map->render();
	for (std::list<Item*>::iterator iter = m_item.begin(); iter != m_item.end(); iter++)
	{
		(*iter)->draw();
	}
	for (std::list<HpPacman*>::iterator iter = mHpPacman.begin(); iter != mHpPacman.end(); iter++)
	{
		(*iter)->draw();
	}
	for (std::list<GhostEnemy*>::iterator iter = mGhostEnemy.begin(); iter != mGhostEnemy.end(); iter++)
	{
		(*iter)->draw();
	}
	m_pacman->draw();
	m_ghost->draw();	
	for (std::list<EnemyManager*>::iterator iter = mEnemyGhost.begin(); iter != mEnemyGhost.end(); iter++)
	{
		(*iter)->draw();
	}
}

void PlayState::hangdler()
{
	TheInputHangdler::Instance()->update();
}

void PlayState::update()
{
	
	m_pacman->update();
	Point possition_pacman;
	Vector2D velocity_pacman;
	velocity_pacman.m_x = m_pacman->getVelocity().m_x;
	velocity_pacman.m_y = m_pacman->getVelocity().m_y;
	
	possition_pacman.x = m_pacman->getPosition().x;
	possition_pacman.y = m_pacman->getPosition().y;

	Point m_positionRed;
	m_positionRed.x = m_ghost->getPosition().x;
	m_positionRed.y = m_ghost->getPosition().y;
	for (std::list<EnemyManager*>::iterator iter = mEnemyGhost.begin(); iter != mEnemyGhost.end(); iter++)
	{
		(*iter)->update(possition_pacman, velocity_pacman, m_positionRed);
	}

	for (std::list<GhostEnemy*>::iterator iter = mGhostEnemy.begin(); iter != mGhostEnemy.end(); iter++)
	{
		(*iter)->setPositionPacman(possition_pacman);
		(*iter)->update();
	}
	
	m_ghost->setPositionPacman(possition_pacman);
	m_ghost->update();
	for (std::list<Item*>::iterator iter = m_item.begin(); iter != m_item.end(); iter++)
	{
		
		int x = (*iter)->getPosition().x;
		int y = (*iter)->getPosition().y;

		int _x = m_pacman->getPosition().x;
		int _y = m_pacman->getPosition().y;
		int a = (x - _x)*(x - _x) + (y - _y)*(y - _y);
		if (a <= 20)
		{
			int idTitles = m_map->findIdTitles(x, y);
			m_map->getLocationTitles()[idTitles] = 0;
			delete(*iter);
			(*iter) = NULL;
		}

	}
	m_item.remove(NULL);

}



bool PlayState::init()
{
	m_map = new Map(TheGame::Instance()->getRenderer());
	m_map->loadFile("FileData/MapInfo.txt");
	m_pacman = new Player();
	m_ghost = new Ghost();
	//mEnemyGhost = new EnemyManager();

	for (int i = 0; i < m_map->getNumberTitles(); i++)
	{
		int y = i / 30;
		y *= 20;
		int x = i % 30;
		x *= 20;
		int w = 20;
		int h = 20;
		Sprite _sprite_item;
		_sprite_item.loadFile("FileData/ImageInfo.txt");

		Sprite pacman;
		pacman.loadFile("FileDaTa/GameObject.txt");
		int id = 0;
		int m_idGhost = 8;
		m_ghost->add(pacman, m_idGhost, TheGame::Instance()->getRenderer(), m_map);
		m_pacman->add(pacman, id, TheGame::Instance()->getRenderer(), m_map);

		if (m_map->getLocationTitles()[i] == 0 || m_map->getLocationTitles()[i] == 8)
		{
			//count++;
			Item * _item = new Item();
			int _id = 4;
	
			_sprite_item.setDrawingCoordinates(x, y, w, h, _id);
			_item->add(_sprite_item, _id, TheGame::Instance()->getRenderer(), m_map);
			m_item.push_back(_item);
		}
		else if (m_map->getLocationTitles()[i] == 6)
		{
			HpPacman* _hpPacman = new HpPacman();
			int _id = 2;
			_sprite_item.setDrawingCoordinates(x, y, w, h, _id);

			_hpPacman->add(_sprite_item, _id, TheGame::Instance()->getRenderer(), m_map);
			mHpPacman.push_back(_hpPacman);
		}
		if (m_map->getLocationTitles()[i] == 8)
		{
			GhostEnemy* _ghostEnemy = new GhostEnemy();
			int _id = 5;
			_sprite_item.setDrawingCoordinates(x, y, w, h, _id);

			_ghostEnemy->add(_sprite_item, _id, TheGame::Instance()->getRenderer(), m_map);
			mGhostEnemy.push_back(_ghostEnemy);
		}
		else if (m_map->getLocationTitles()[i] == 7)
		{
			int m_idGhotsPink = 16; // id sprite for ghost pink

			pacman.setDrawingCoordinates(x, y, w, h, m_idGhotsPink);
			EnemyManager* _EnemyGhost;
			_EnemyGhost = new EnemyManager();
			_EnemyGhost->add(pacman, m_idGhotsPink, TheGame::Instance()->getRenderer(), m_map);
			_EnemyGhost->creatGhostPink(15);
			mEnemyGhost.push_back(_EnemyGhost);
		}
		else if (m_map->getLocationTitles()[i] == 9)
		{
			int m_idGhostBlue = 25;

			pacman.setDrawingCoordinates(x, y, w, h, m_idGhostBlue);
			EnemyManager* _EnemyGhost;
			_EnemyGhost = new EnemyManager();
			_EnemyGhost->add(pacman, m_idGhostBlue, TheGame::Instance()->getRenderer(), m_map);
			_EnemyGhost->creatGhostBlue(25);
			mEnemyGhost.push_back(_EnemyGhost);
		}
	}

	std::cout << "Play state" << endl;
	
	return true;
}

void PlayState::m_pause()
{
	m_bPause = true;
	int a = 0;
	std::cout << "Pause state clicked." << endl;
	TheGame::Instance()->getStateMachine()->changeState(new PauseState());
}

bool PlayState::exit()
{
	return true;
}

string PlayState::getStateID() const
{
	return s_playID;
}


void PlayState::addCreep()
{

}

bool PlayState::checkCollisionBox(SDL_Rect objectImageFirs, SDL_Rect objectImageTwo)
{
	int topBoxImage, butomBoxImage, leftBoxImage, rightBoxImage;
	int topBoxImageTwo, butomBoxImageTwo, leftBoxImageTwo, rightBoxImageTwo;

	// 
	topBoxImage = objectImageFirs.y;
	butomBoxImage = objectImageFirs.y + objectImageFirs.h;
	leftBoxImage = objectImageFirs.x;
	rightBoxImage = objectImageFirs.x + objectImageFirs.w;
	//

	//
	topBoxImageTwo = objectImageTwo.y;
	butomBoxImageTwo = objectImageTwo.h + objectImageTwo.y;
	leftBoxImageTwo = objectImageTwo.x;
	rightBoxImageTwo = objectImageTwo.w + objectImageTwo.x;

	if (topBoxImage >= butomBoxImageTwo || butomBoxImage <= topBoxImageTwo ||
		leftBoxImage >= rightBoxImageTwo || rightBoxImage <= leftBoxImageTwo)
	{
		// the box have not colised
		return false;
	}

	// if the box have colised
	else
		return true;
}

bool PlayState::checkCollisionSquare(cSquare &A, cSquare &B)
{
	int xA, yA, rA;
	int xB, yB, rB;

	xA = A.x_center; yA = A.y_center; rA = A.radius;
	xB = B.x_center; yB = B.y_center; rB = B.radius;

	double lenght = sqrt(pow(xA + xB, 2) + pow(yA + yB, 2));
	if (rA + rB <= lenght)
	{
		// if not
		return false;
	}

	// the circles have colised
	return true;
}

bool PlayState::checkPixelBased(std::vector<SDL_Rect> &A, std::vector<SDL_Rect> &B)
{
	int leftA, rightA, topA, bottomA;
	int leftB, rightB, topB, bottomB;

	// A box
	for (int iBox = 0; iBox < A.size(); iBox)
	{
		leftA = A[iBox].x;
		rightA = A[iBox].x + A[iBox].w;
		topA = A[iBox].y;
		bottomA = A[iBox].y + A[iBox].h;
		// B box
		for (int jBox = 0; jBox < B.size(); jBox)
		{
			leftB = B[iBox].x;
			rightB = B[iBox].x + B[iBox].w;
			topB = B[iBox].y;
			bottomB = B[iBox].y + B[iBox].h;
			if (((bottomA <= topB) || (topA >= bottomB) || (rightA <= leftB) || (leftA >= rightB)) == false)
			{
				//A collision is detected
				return true;
			}
		}
		// 
		return false;
	}
}